// ==========================================================================
// gin-sns自动生成业务逻辑层相关代码，只生成一次，按需修改,再次生成不会覆盖.
// date：2021-02-21 13:45:53 +0800 CST
// path: app/service/module/article_service.go
// author：jon
// ==========================================================================
package module

import (
	"errors"
	"gin-sns/app/dao/module/article"
	"gin-sns/app/dao/module/tag"
	"gin-sns/app/model"
	"gin-sns/app/model/constants"
	articleModel "gin-sns/app/model/module/article"
	entitytagModel "gin-sns/app/model/module/entitytag"
	tagModel "gin-sns/app/model/module/tag"
	"strings"
	"time"

	"github.com/gin-gonic/gin"

	"gin-sns/app/ginframe/utils/convert"
	"gin-sns/app/ginframe/utils/page"
)

var ArticleService = newArticleService()

func newArticleService() *articleService {
	return &articleService{}
}

type articleService struct {
}

//根据主键查询数据
func (s *articleService) SelectRecordById(id int64) (*articleModel.Entity, error) {
	return article.ArticleDao.SelectById(id)
}

//
func (s *articleService) SelectRecordsIn(idarr []int64) ([]articleModel.Entity, error) {

	list, err := article.ArticleDao.FindIn("id", idarr)
	if list != nil && len(list) > 0 {
		err = errors.New("not found")
		list = nil
	}
	return list, err
}

//根据主键删除数据
func (s *articleService) DeleteRecordById(id int64) bool {
	return article.ArticleDao.DeleteById(id)
}

//批量删除数据记录
func (s *articleService) DeleteRecordByIds(ids string) int64 {
	ida := convert.ToInt64Array(ids, ",")
	result, err := article.ArticleDao.DeleteBatch(ida...)
	if err != nil {
		return 0
	}
	return result
}

//添加数据
func (s *articleService) AddSave(req *articleModel.AddReq, ctx *gin.Context) (int64, error) {
	var entity articleModel.Entity

	//entity.Id = req.Id
	entity.CategoryId = req.CategoryId
	entity.UserId = req.UserId
	entity.Title = req.Title
	entity.Summary = req.Summary
	entity.Content = req.Content
	entity.Tags = req.Tags
	entity.Recommend = req.Recommend
	entity.Share = req.Share
	entity.ContentType = req.ContentType
	entity.SourceUrl = req.SourceUrl
	entity.CountView = req.CountView
	entity.CountLike = req.CountLike
	entity.CountReward = req.CountReward
	entity.CountFavor = req.CountFavor
	entity.CountShare = req.CountShare
	entity.CountComment = req.CountComment
	entity.Status = req.Status
	entity.LastCommentTime = req.LastCommentTime
	entity.CreateTime = time.Now()
	//entity.CreateBy = ""

	//user := system.UserService.GetProfile(ctx)

	//if user != nil {
	//	entity.CreateBy = user.LoginName
	//}

	_, err := article.ArticleDao.Insert(&entity)
	return entity.Id, err
}

//修改数据
func (s *articleService) EditSave(req *articleModel.EditReq, ctx *gin.Context) (int64, error) {
	entity := &articleModel.Entity{Id: req.Id}
	ok, err := article.ArticleDao.FindOne(entity)

	if err != nil {
		return 0, err
	}

	if !ok {
		return 0, errors.New("数据不存在")
	}

	entity.CategoryId = req.CategoryId
	entity.UserId = req.UserId
	entity.Title = req.Title
	entity.Summary = req.Summary
	entity.Content = req.Content
	entity.Tags = req.Tags
	entity.Recommend = req.Recommend
	entity.Share = req.Share
	entity.ContentType = req.ContentType
	entity.SourceUrl = req.SourceUrl
	entity.CountView = req.CountView
	entity.CountLike = req.CountLike
	entity.CountReward = req.CountReward
	entity.CountFavor = req.CountFavor
	entity.CountShare = req.CountShare
	entity.CountComment = req.CountComment
	entity.Status = req.Status
	entity.LastCommentTime = req.LastCommentTime
	//entity.UpdateTime = time.Now()
	//entity.UpdateBy = ""

	//user := system.UserService.GetProfile(ctx)

	//if user == nil {
	//	entity.UpdateBy = user.LoginName
	//}

	return article.ArticleDao.Update(entity)
}

//根据条件查询数据
func (s *articleService) SelectListAll(params *articleModel.SelectPageReq) ([]articleModel.Entity, error) {
	return article.ArticleDao.SelectListAll(params)
}

//根据条件分页查询数据
func (s *articleService) SelectListByPage(params *articleModel.SelectPageReq) ([]articleModel.Entity, *page.Paging, error) {
	return article.ArticleDao.SelectListByPage(params)
}

// 导出excel
func (s *articleService) Export(param *articleModel.SelectPageReq) (string, error) {
	head := []string{"id", "分类id", "用户id", "标题", "摘要", "内容", "标签", "推荐设置，数字越大越靠前", "", "内容类型", "url", "阅读数量", "赞同数量", "打赏数量", "收藏数量", "分享数量", "评论数量", "0未审核 1正常状态 2审核未通过 3删除", "创建时间", "更新时间", "最后评论时间"}
	col := []string{"id", "category_id", "user_id", "title", "summary", "content", "tags", "recommend", "share", "content_type", "source_url", "count_view", "count_like", "count_reward", "count_favor", "count_share", "count_comment", "status", "create_time", "update_time", "last_comment_time"}
	return article.ArticleDao.SelectListExport(param, head, col)
}

// 获取文章对应的标签
func (s *articleService) GetArticleTags(articleId int64) []tagModel.Entity {
	req := new(entitytagModel.SelectPageReq)
	req.EntityId = articleId
	req.EntityType = constants.EntityTypeArticle

	articleTags, _ := EntitytagService.SelectListAll(req)

	var tagIds []int64
	for _, articleTag := range articleTags {
		tagIds = append(tagIds, articleTag.TagId)
	}

	//return cache.TagCache.GetList(tagIds)
	list, err := tag.TagDao.FindIn("id", tagIds)
	if err != nil || list == nil || len(list) == 0 {
		return nil
	}

	return list
}

// 标签文章列表
func (s *articleService) GetTagArticles(tagId int64, cursor int64) (articles []articleModel.Entity, nextCursor int64) {

	req := new(entitytagModel.SelectPageReq)
	req.TagId = tagId
	req.Status = model.ArticleTagStatusOk
	req.EntityType = constants.EntityTypeArticle
	//req.PageNum = cursor

	articleTags, _ := EntitytagService.SelectListAll(req)

	var articleIds []int64
	for _, articleTag := range articleTags {
		articleIds = append(articleIds, articleTag.EntityId)
	}

	list, err := article.ArticleDao.FindIn("id", articleIds)
	if err != nil || list == nil || len(list) == 0 {
		return nil, 0
	}

	return list, 0
}

// 分类文章列表
func (s *articleService) GetCategoryArticles(categoryId int64, cursor int64) (articles []articleModel.Entity, nextCursor int64) {

	req := new(articleModel.SelectPageReq)
	req.CategoryId = categoryId
	req.Status = model.ArticleTagStatusOk

	list, _ := article.ArticleDao.SelectListAll(req)

	return list, 0
}

// 发布文章
func (s *articleService) Publish(userId int64, title, summary, content, contentType string, categoryId int64,
	tags []string, sourceUrl string, share bool) (art *articleModel.Entity, err error) {

	title = strings.TrimSpace(title)
	summary = strings.TrimSpace(summary)
	content = strings.TrimSpace(content)

	if len(title) == 0 {
		return nil, errors.New("标题不能为空")
	}
	//if share { // 如果是分享的内容，必须有Summary和SourceUrl
	if len(summary) == 0 {
		return nil, errors.New("分享内容摘要不能为空")
	}
	if len(sourceUrl) == 0 {
		return nil, errors.New("分享内容原文链接不能为空")
	}
	//} else {
	if len(content) == 0 {
		return nil, errors.New("内容不能为空")
	}
	//}
	entity := &articleModel.Entity{
		UserId:      userId,
		Title:       title,
		Summary:     summary,
		Content:     content,
		ContentType: contentType,
		CategoryId:  categoryId,
		Status:      model.ArticleStatusPublished,
		//Share:       share,
		Tags:       strings.Join(tags, ","),
		SourceUrl:  sourceUrl,
		CreateTime: time.Now(),
		UpdateTime: time.Now(),
	}

	_, err = article.ArticleDao.Insert(entity)
	if err != nil {
		return nil, err
	}

	tagIds := TagService.GetOrCreates(tags)
	EntitytagService.AddArticleTags(entity.Id, tagIds)

	//if err == nil {
	//	blogService.AnalyzeArticle(article)
	//}
	return entity, nil
}

// 修改文章
func (s *articleService) Edit(articleId int64, tags []string, title, content string) error {
	if len(title) == 0 {
		return errors.New("请输入标题")
	}
	if len(content) == 0 {
		return errors.New("请填写文章内容")
	}

	req := new(articleModel.EditReq)
	req.Title = title
	req.Content = content
	rs, err := s.EditSave(req, nil) //c
	if err != nil || rs <= 0 {
		return err
	}

	tagIds := TagService.GetOrCreates(tags)            // 创建文章对应标签
	EntitytagService.DeleteArticleTags(articleId)      // 先删掉所有的标签
	EntitytagService.AddArticleTags(articleId, tagIds) // 然后重新添加标签

	return nil
}

// 相关文章
func (s *articleService) GetRelatedArticles(articleId int64) []articleModel.Entity {
	//tagIds := cache.ArticleTagCache.Get(articleId)
	//if len(tagIds) == 0 {
	//	return nil
	//}
	var articles []articleModel.Entity

	tags := s.GetArticleTags(articleId)
	if len(tags) == 0 {
		return nil
	}

	for _, tag := range tags {
		list, _ := s.GetTagArticles(tag.Id, 0)
		if list != nil && len(list) > 0 {
			articles = append(list)

		}

	}

	return articles
}

func (s *articleService) GetArticlesByUrl(url string) []articleModel.Entity {
	req := new(articleModel.SelectPageReq)
	req.SourceUrl = url
	list, _ := s.SelectListAll(req)

	return list
}

// 最新文章
func (s *articleService) GetNewestArticles(limit int, start int) []articleModel.Entity {
	list, _ := article.ArticleDao.GetNewestArticles(limit, start)
	return list
}

func (s *articleService) GetUserNewestArticles(userId int64, size int, page int) []articleModel.Entity {
	list, _ := article.ArticleDao.GetUserNewestArticles(userId, size, page)
	return list
}

// 浏览数+1
func (s *articleService) IncrViewCount(articleId int64) {
	article.ArticleDao.IncrViewCount(articleId)
}

func (s *articleService) IncrLikeCount(articleId int64) {
	article.ArticleDao.IncrLikeCount(articleId)
}

func (s *articleService) DecrLikeCount(articleId int64) {
	article.ArticleDao.DecrLikeCount(articleId)
}

func (s *articleService) IncrFavoriteCount(articleId int64) {
	article.ArticleDao.IncrFavoriteCount(articleId)
}

func (s *articleService) DecrFavoriteCount(articleId int64) {
	article.ArticleDao.DecrFavoriteCount(articleId)
}

func (s *articleService) IncrRewardCount(answerId int64) {
	article.ArticleDao.IncrRewardCount(answerId)
}
func (s *articleService) DecrRewardCount(answerId int64) {
	article.ArticleDao.DecrRewardCount(answerId)
}
